home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xvmines-.0 / xvmines- / xvmines-1.0 / xvmines.c < prev    next >
C/C++ Source or Header  |  1995-04-20  |  15KB  |  580 lines

  1. #include <math.h>
  2. #include <sys/types.h>
  3. #include <sys/timeb.h>
  4. #include <sys/time.h>
  5. #include <stdio.h>
  6. #include <X11/Xlib.h>
  7. #include <X11/Xutil.h>
  8. #include <xview/xview.h>
  9. #include <xview/panel.h>
  10. #include <xview/frame.h>
  11. #include <xview/canvas.h>
  12. #include <xview/notice.h>
  13. #include <xview/cms.h>
  14. #include <xview/font.h>
  15.  
  16. #include "xvmines.h"
  17. #include "version.h"
  18.  
  19. #include "xvmines.icons"
  20.  
  21. #define CREATE_ICON(bits,width,height) \
  22.                 XCreateBitmapFromData(display,RootWindow(display,screen),\
  23.                     bits,width,height)
  24. /* #define DEBUG */
  25.  
  26. #ifndef lint
  27. static char     sccsid[] = "@(#)xvmines,v0.2 by Manolis Lourakis.";
  28. static char     Copyright[] = "(c) 1992 Manolis Lourakis.\n";
  29. static char     Mail[] = "lourakis@csd.uch.gr";
  30. #endif
  31.  
  32. #define T_FONT_NAME "-adobe-*-*-*-normal-*-12-*-*-*-*-*-*-*"
  33.  
  34.  
  35. extern char    *optarg;
  36. extern int      optind;
  37.  
  38. #ifdef __STDC__
  39. void            canvas_event_proc(Xv_Window, Event *);
  40. void            canvas_repaint_proc(void);
  41. void            finish(char *);
  42. void            print_string(char *, int, int, int);
  43. #else
  44. void            canvas_event_proc();
  45. void            canvas_repaint_proc();
  46. void            finish();
  47. void            print_string();
  48. #endif
  49.  
  50.  
  51. Display        *display;
  52. Visual         *visual;
  53. int             screen;
  54. GC              def_gc;
  55.  
  56. Frame           frame;
  57. Panel           panel1;
  58. Panel_item      opt;
  59. Canvas          canvas, msg_canvas;
  60.  
  61. Window          dr_win;
  62. Pixmap          pmap, icons[NUM_ICONS];
  63. cell           *Cells;
  64. char            buff[256];
  65.  
  66. Notify_func     active_func = NOTIFY_FUNC_NULL;
  67.  
  68. int             quit_proc(), init(), restart(), hide_cmd_frame();
  69.  
  70. #ifdef __STDC__
  71. int             adj_mine_num(Panel_item, Event *), adj_size(Panel_item, Event *),
  72.                 show_cmd_frame(Menu, Menu_item);
  73. int             place_tiles(int, int, int),
  74.                 mark_tile(int, int),
  75.                 open_tile(int, int),
  76.                 auto_open(int, int);
  77. Frame           create_cmd_frame(Frame, char *, int (*notifier) ());
  78. #else
  79. int             adj_mine_num(), adj_size(), show_cmd_frame();
  80. int             place_tiles(), mark_tile(), open_tile(), auto_open();
  81. Frame           create_cmd_frame();
  82. #endif
  83.  
  84. int             mines_2_go, closed_tiles, playing, first, checks, secs;
  85. int             first_tile;
  86. int             width = HORIZ_CELLS, height = VERT_CELLS, mines = NUM_MINES,
  87.                 quantum = QUANTUM;
  88.  
  89. struct itimerval timer;
  90.  
  91. #ifdef __STDC__
  92. int
  93. main(int argc, char *argv[])
  94. #else
  95. int
  96. main(argc, argv)
  97.     int             argc;
  98.     char           *argv[];
  99. #endif
  100. {
  101.     int             ret, tmp;
  102.     register int    i, j;
  103.     int             errflag = 0, badparam = 0, gc;
  104.     XWMHints        wm_hints;
  105.     XClassHint      class_hints;
  106.     XTextProperty   windowName, iconName;
  107.     char           *window_name = version_string;
  108.     char           *icon_name = version_string;
  109.     Menu            menu;
  110.     Menu_item       entry1, entry2, entry3;
  111.     Frame           aux_fr;
  112.     Cms             cms;
  113.  
  114.     xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
  115.     while ((gc = getopt(argc, argv, "w:h:m:q:")) != EOF)
  116.         switch (gc) {
  117.         case 'w':
  118.             tmp = atoi(optarg);
  119.             if (tmp > 0 && tmp <= MAX_WIDTH)
  120.                 width = tmp;
  121.             else
  122.                 badparam++;
  123.             break;
  124.         case 'h':
  125.             tmp = atoi(optarg);
  126.             if (tmp > 0 && tmp <= MAX_HEIGHT)
  127.                 height = tmp;
  128.             else
  129.                 badparam++;
  130.             break;
  131.         case 'm':
  132.             tmp = atoi(optarg);
  133.             if (tmp > 0)
  134.                 mines = tmp;
  135.             else
  136.                 badparam++;
  137.             break;
  138.         case 'q':
  139.             tmp = atoi(optarg);
  140.             if (tmp > 0)
  141.                 quantum = tmp;
  142.             else
  143.                 badparam++;
  144.             break;
  145.         case '?':
  146.             errflag++;
  147.             break;
  148.         }
  149.     if (badparam) {
  150.         fprintf(stderr,
  151.             "xvmines: Bad argument(s).\n");
  152.         exit(1);
  153.     }
  154.     if (errflag) {
  155.         fprintf(stderr,
  156.             "Usage: xvmines [-w width] [-h height] [-m mines] [-q quantum]\n");
  157.         exit(1);
  158.     }
  159.     if (mines > width * height) {
  160.         fprintf(stderr, "xvmines: Too many mines, using defaults\n");
  161.         width = HORIZ_CELLS;
  162.         height = VERT_CELLS;
  163.         mines = NUM_MINES;
  164.     }
  165.     Cells = (cell *) malloc(width * height * sizeof(cell));
  166.     if (Cells == NULL) {
  167.         fprintf(stderr, "xvmines: malloc failed\n");
  168.         exit(1);
  169.     }
  170.     cms = xv_create(NULL, CMS,
  171.             CMS_SIZE, CMS_CONTROL_COLORS + 1,
  172.             CMS_CONTROL_CMS, True,
  173.             CMS_NAMED_COLORS, "red", NULL,
  174.             NULL);
  175.  
  176.     frame = (Frame) xv_create(NULL, FRAME,
  177.                   FRAME_LABEL, version_string,
  178.                   XV_WIDTH, width * IC_WIDTH,
  179.                   WIN_CMS, cms,
  180.                   FRAME_SHOW_FOOTER, TRUE,
  181.                   FRAME_LEFT_FOOTER, "",
  182.                   FRAME_RIGHT_FOOTER, "",
  183.                   NULL);
  184.     display = (Display *) xv_get(frame, XV_DISPLAY);
  185.     screen = DefaultScreen(display);
  186.     visual = DefaultVisual(display, screen);
  187.     def_gc = DefaultGC(display, screen);
  188.  
  189.     panel1 = xv_create(frame, PANEL,
  190.                PANEL_LAYOUT, PANEL_HORIZONTAL,
  191.                NULL);
  192.  
  193.     xv_create(panel1, PANEL_BUTTON,
  194.           PANEL_LABEL_STRING, "Quit",
  195.           PANEL_NOTIFY_PROC, quit_proc,
  196.           NULL);
  197.     xv_create(panel1, PANEL_BUTTON,
  198.           PANEL_LABEL_STRING, "New",
  199.           PANEL_NOTIFY_PROC, restart,
  200.           NULL);
  201.     aux_fr = create_cmd_frame(frame, "New number of mines: ", adj_mine_num);
  202.     entry1 = (Menu_item) xv_create((unsigned long) NULL, MENUITEM,
  203.                        MENU_STRING, "Mines",
  204.                        XV_KEY_DATA, KEY, aux_fr,
  205.                        MENU_NOTIFY_PROC, show_cmd_frame,
  206.                        NULL);
  207.     aux_fr = create_cmd_frame(frame, "New dimensions (wxh): ", adj_size);
  208.     entry2 = (Menu_item) xv_create((unsigned long) NULL, MENUITEM,
  209.                        MENU_STRING, "Dimensions",
  210.                        XV_KEY_DATA, KEY, aux_fr,
  211.                        MENU_NOTIFY_PROC, show_cmd_frame,
  212.                        NULL);
  213.     menu = (Menu) xv_create((unsigned long) NULL, MENU,
  214.                 MENU_APPEND_ITEM, entry1,
  215.                 MENU_APPEND_ITEM, entry2,
  216.                 NULL);
  217.  
  218.     opt = xv_create(panel1, PANEL_BUTTON,
  219.             PANEL_LABEL_STRING, "Options",
  220.             PANEL_ITEM_MENU, menu,
  221.             NULL);
  222.  
  223.     window_fit_height(panel1);
  224.     msg_canvas = xv_create(frame, CANVAS,
  225.                    XV_HEIGHT, MSG_CANVAS_HEIGHT,
  226.                    NULL);
  227.  
  228.     sprintf(buff, "Mines: %d\n", mines);
  229.     xv_set(frame, FRAME_LEFT_FOOTER, buff, NULL);
  230.     sprintf(buff, "Checks: 0");
  231.     xv_set(frame, FRAME_RIGHT_FOOTER, buff, NULL);
  232.     /* window_fit_height(panel2); */
  233.  
  234.     canvas = xv_create(frame, CANVAS,
  235.                CANVAS_X_PAINT_WINDOW, TRUE,
  236.                XV_WIDTH, IC_WIDTH * width,
  237.                XV_HEIGHT, IC_HEIGHT * height,
  238.                WIN_EVENT_PROC, canvas_event_proc,
  239.                CANVAS_REPAINT_PROC, canvas_repaint_proc,
  240.                NULL);
  241.     xv_set(canvas_paint_window(canvas),
  242.            WIN_CONSUME_X_EVENT_MASK,
  243.            ButtonPressMask | ButtonReleaseMask |
  244.            EnterWindowMask | LeaveWindowMask,
  245.            WIN_EVENT_PROC, canvas_event_proc,
  246.            NULL);
  247.  
  248.     dr_win = xv_get(canvas_paint_window(canvas), XV_XID);
  249.  
  250.     pmap = XCreatePixmap(display, dr_win, IC_WIDTH * width,
  251.              IC_HEIGHT * height, DefaultDepth(display, screen));
  252.  
  253.     icons[EMPTY] = CREATE_ICON(empty_bits, empty_width, empty_height);
  254.     icons[ONE] = CREATE_ICON(one_bits, one_width, one_height);
  255.     icons[TWO] = CREATE_ICON(two_bits, two_width, two_height);
  256.     icons[THREE] = CREATE_ICON(three_bits, three_width, three_height);
  257.     icons[FOUR] = CREATE_ICON(four_bits, four_width, four_height);
  258.     icons[FIVE] = CREATE_ICON(five_bits, five_width, five_height);
  259.     icons[SIX] = CREATE_ICON(six_bits, six_width, six_height);
  260.     icons[SEVEN] = CREATE_ICON(seven_bits, seven_width, seven_height);
  261.     icons[EIGHT] = CREATE_ICON(eight_bits, eight_width, eight_height);
  262.     icons[CLOSED] = CREATE_ICON(closed_bits, closed_width, closed_height);
  263.     icons[MARKED] = CREATE_ICON(marked_bits, marked_width, marked_height);
  264.     icons[MINE] = CREATE_ICON(mine_bits, mine_width, mine_height);
  265.     icons[QUEST] = CREATE_ICON(quest_bits, quest_width, quest_height);
  266.  
  267.     if (XStringListToTextProperty(&window_name, 1, &windowName) == 0) {
  268.         fprintf(stderr, "structure allocation for windowName failed\n");
  269.         exit(1);
  270.     }
  271.     if (XStringListToTextProperty(&icon_name, 1, &iconName) == 0) {
  272.         fprintf(stderr, "structure allocation for windowName failed\n");
  273.         exit(1);
  274.     }
  275.     wm_hints.initial_state = NormalState;
  276.     wm_hints.input = True;
  277.     wm_hints.icon_pixmap = icons[MINE];
  278.     wm_hints.flags = StateHint | IconPixmapHint | InputHint;
  279.  
  280.     class_hints.res_name = "XVmines";
  281.     class_hints.res_class = "Games";
  282.  
  283.     XSetWMProperties(display, xv_get(frame, XV_XID), &windowName, &iconName, argv,
  284.              argc, NULL, &wm_hints, &class_hints);
  285.  
  286.  
  287.  
  288.     timer.it_interval.tv_sec = quantum;
  289.     timer.it_interval.tv_usec = 0;
  290.  
  291.     timer.it_value.tv_sec = quantum;
  292.     timer.it_value.tv_usec = 0;
  293.  
  294.     init();
  295.     window_fit(frame);
  296.     xv_main_loop(frame);
  297. }
  298.  
  299.  
  300. void
  301. canvas_repaint_proc()
  302. {
  303.     XCopyArea(display, pmap, dr_win, def_gc, 0, 0,
  304.           width * IC_WIDTH, height * IC_HEIGHT, 0, 0);
  305. }
  306.  
  307. #ifdef __STDC__
  308. void
  309. canvas_event_proc(Xv_Window window, Event * event)
  310. #else
  311. void
  312. canvas_event_proc(window, event)
  313.     Xv_Window       window;
  314.     Event          *event;
  315. #endif
  316. {
  317.     int             x, y, which;
  318.     cell           *aux;
  319.  
  320. #ifdef DEBUG
  321.     printf("Mines to go %d,checks %d closed %d\n", mines_2_go, checks, closed_tiles);
  322. #endif
  323.  
  324.     if (!playing)
  325.         return;
  326.     switch (event_xevent(event)->type) {
  327.     case ButtonRelease:
  328.         get_cell(event_xevent(event)->xbutton.x, event_xevent(event)->xbutton.y,
  329.              &x, &y);
  330.         if (first) {
  331.             place_tiles(width * height, mines, x * width + y);
  332.             xv_set(opt, PANEL_INACTIVE, TRUE, NULL);
  333.             print_string("Time->> 0:0", TIME_X, TIME_Y, CLEAR_YES);
  334.             first = FALSE;
  335.         }
  336.         switch (event_xevent(event)->xbutton.button) {
  337.         case Button1:
  338.             if (open_tile(x, y)) {
  339.                 XCopyArea(display, pmap, dr_win, def_gc, 0, 0,
  340.                 width * IC_WIDTH, height * IC_HEIGHT, 0, 0);
  341.             }
  342.             if (mines_2_go == 0 && closed_tiles == mines)
  343.                 finish("  Successful");
  344.             break;
  345.         case Button2:
  346.             aux = Cells + x * width + y;
  347.             if (aux->out_state != QUEST && aux->out_state != CLOSED)
  348.                 break;
  349.             which = (aux->out_state == CLOSED) ? QUEST : CLOSED;
  350.             PLACE_ICON(icons[which], x * IC_WIDTH,
  351.                    y * IC_HEIGHT);
  352.             aux->out_state = which;
  353.             XCopyArea(display, pmap, dr_win, def_gc, 0, 0,
  354.                 width * IC_WIDTH, height * IC_HEIGHT, 0, 0);
  355.             break;
  356.         case Button3:
  357.             if (mark_tile(x, y)) {
  358.                 XCopyArea(display, pmap, dr_win, def_gc, 0, 0,
  359.                 width * IC_WIDTH, height * IC_HEIGHT, 0, 0);
  360.             }
  361.             if (mines_2_go == 0 && closed_tiles == mines)
  362.                 finish("  Successful");
  363.  
  364.             break;
  365.         }
  366.         break;
  367.     case EnterNotify:
  368.         notify_set_itimer_func(canvas, active_func, ITIMER_REAL, &timer, NULL);
  369.         break;
  370.     case LeaveNotify:
  371.         notify_set_itimer_func(canvas, NOTIFY_FUNC_NULL, ITIMER_REAL, &timer, NULL);
  372.         break;
  373.     default:
  374.         break;
  375.     }
  376. }
  377.  
  378. quit_proc()
  379. {
  380.     int             result;
  381.  
  382.     result = notice_prompt(panel1, NULL,
  383.                    NOTICE_MESSAGE_STRINGS,
  384.                    "Really Quit?",
  385.                    "Press YES to confirm",
  386.                    "Press NO to cancel",
  387.                    NULL,
  388.                    NOTICE_BUTTON_YES, "YES",
  389.                    NOTICE_BUTTON_NO, "NO",
  390.                    NULL);
  391.  
  392.     switch (result) {
  393.     case NOTICE_YES:
  394.         exit(0);
  395.         break;
  396.     case NOTICE_NO:
  397.         break;
  398.     case NOTICE_FAILED:
  399.     default:
  400.         break;
  401.     }
  402. }
  403.  
  404. #ifdef __STDC__
  405. int
  406. adj_mine_num(Panel_item item, Event * event)
  407. #else
  408. int
  409. adj_mine_num(item, event)
  410.     Panel_item      item;
  411.     Event          *event;
  412. #endif
  413. {
  414.     mines = atoi((char *) xv_get(item, PANEL_VALUE));
  415.     xv_set((Frame) xv_get(item, PANEL_CLIENT_DATA), XV_SHOW, FALSE, NULL);
  416.  
  417.     if (mines > width * height || mines <= 0) {
  418.         fprintf(stderr, "xvmines: Invalid number of mines specified, using defaults\n");
  419.         if (NUM_MINES < width * height)
  420.             mines = NUM_MINES;
  421.         else
  422.             mines = width;
  423.     }
  424.     sprintf(buff, "Mines: %d\n", mines);
  425.     xv_set(frame, FRAME_LEFT_FOOTER, buff, NULL);
  426.     init();
  427.  
  428. }
  429.  
  430. #ifdef __STDC__
  431. int
  432. adj_size(Panel_item item, Event * event)
  433. #else
  434. int
  435. adj_size(item, event)
  436.     Panel_item      item;
  437.     Event          *event;
  438. #endif
  439. {
  440.     int             frame_height, n;
  441.  
  442.     n = sscanf((char *) xv_get(item, PANEL_VALUE), "%dx%d", &width, &height);
  443.     xv_set((Frame) xv_get(item, PANEL_CLIENT_DATA), XV_SHOW, FALSE, NULL);
  444.     if (n != 2 || width <= 0 || width > MAX_WIDTH || height <= 0 || height > MAX_HEIGHT) {
  445.         fprintf(stderr, "xvmines: Invalid dimensions specified,using defaults\n");
  446.         width = HORIZ_CELLS;
  447.         height = VERT_CELLS;
  448.     }
  449.  
  450.     XFreePixmap(display, pmap);
  451.     pmap = XCreatePixmap(display, dr_win, IC_WIDTH * width,
  452.              IC_HEIGHT * height, DefaultDepth(display, screen));
  453.     frame_height = height * IC_HEIGHT + xv_get(panel1, XV_HEIGHT) +
  454.         xv_get(msg_canvas, XV_HEIGHT);
  455.  
  456.  
  457.     xv_set(frame, XV_WIDTH, width * IC_WIDTH,
  458.            XV_HEIGHT, frame_height,
  459.            NULL);
  460.     xv_set(canvas, XV_WIDTH, width * IC_WIDTH,
  461.            XV_HEIGHT, height * IC_HEIGHT,
  462.            NULL);
  463.     free(Cells);
  464.     Cells = (cell *) malloc(width * height * sizeof(cell));
  465.     if (Cells == NULL) {
  466.         fprintf(stderr, "xvmines: malloc failed\n");
  467.         exit(1);
  468.     }
  469.     init();
  470. }
  471.  
  472. int
  473. restart()
  474. {
  475.     init();
  476.     xv_set(opt, PANEL_INACTIVE, FALSE, NULL);
  477. }
  478.  
  479. #ifdef __STDC__
  480. int
  481. hide_cmd_frame(Panel_item item, Event * event)
  482. #else
  483. int
  484. hide_cmd_frame(item, event)
  485.     Panel_item      item;
  486.     Event          *event;
  487. #endif
  488. {
  489.     xv_set((Frame) xv_get(item, PANEL_CLIENT_DATA), XV_SHOW, FALSE, NULL);
  490. }
  491.  
  492. #ifdef __STDC__
  493. int
  494. show_cmd_frame(Menu menu, Menu_item item)
  495. #else
  496. int
  497. show_cmd_frame(menu, item)
  498.     Menu            menu;
  499.     Menu_item       item;
  500. #endif
  501. {
  502.     xv_set((Frame) xv_get(item, XV_KEY_DATA, KEY), XV_SHOW, TRUE, NULL);
  503. }
  504.  
  505. #ifdef __STDC__
  506. Frame
  507. create_cmd_frame(Frame parent, char *msg, int (*notifier) ())
  508. #else
  509. Frame
  510. create_cmd_frame(parent, msg, notifier)
  511.     Frame           parent;
  512.     char           *msg;
  513.     int             (*notifier) ();
  514. #endif
  515. {
  516.     Frame           popup;
  517.     Panel           aux_pan;
  518.  
  519.     popup = xv_create(parent, FRAME_CMD,
  520.               FRAME_LABEL, "prompt",
  521.               XV_WIDTH, 250,
  522.               XV_HEIGHT, 60,
  523.               XV_X, (int) xv_get(parent, XV_X),
  524.               XV_Y, (int) xv_get(parent, XV_Y),
  525.               NULL);
  526.  
  527.     aux_pan = (Panel) xv_get(popup, FRAME_CMD_PANEL);
  528.     xv_set(aux_pan, PANEL_LAYOUT, PANEL_VERTICAL, NULL);
  529.     xv_create(aux_pan, PANEL_TEXT,
  530.           PANEL_LABEL_STRING, msg,
  531.           PANEL_VALUE_DISPLAY_LENGTH, 5,
  532.           PANEL_VALUE_STORED_LENGTH, 5,
  533.           PANEL_CLIENT_DATA, popup,
  534.           PANEL_NOTIFY_PROC, notifier,
  535.           NULL);
  536.     xv_create(aux_pan, PANEL_BUTTON,
  537.           PANEL_LABEL_STRING, "Cancel",
  538.           PANEL_CLIENT_DATA, popup,
  539.           PANEL_NOTIFY_PROC, hide_cmd_frame,
  540.           NULL);
  541.     return popup;
  542. }
  543.  
  544. #ifdef __STDC__
  545. void
  546. print_string(char *to_print, int x, int y, int clr)
  547. #else
  548. void
  549. print_string(to_print, x, y, clr)
  550.     char           *to_print;
  551.     int             x, y, clr;
  552. #endif
  553. {
  554.     static XFontStruct *t_font = NULL;
  555.     static int      letter_width;
  556.     static int      letter_height;
  557.     static Window   win;
  558.  
  559.     XTextItem       text;
  560.  
  561.     if (t_font == NULL) {
  562.         t_font = XQueryFont(display, XLoadFont(display, T_FONT_NAME));
  563.         if (t_font == NULL) {
  564.             fprintf(stderr,
  565.               "xvmines: Failed to load font %s\n", T_FONT_NAME);
  566.             exit(1);
  567.         }
  568.         letter_width = t_font->max_bounds.rbearing - t_font->min_bounds.lbearing;
  569.         letter_height = t_font->max_bounds.ascent + t_font->max_bounds.descent;
  570.         win = (Window) xv_get(canvas_paint_window(msg_canvas), XV_XID);
  571.     }
  572.     text.chars = to_print;
  573.     text.nchars = strlen(to_print);
  574.     text.delta = 0;
  575.     text.font = t_font->fid;
  576.     if (clr == CLEAR_YES)
  577.         XClearWindow(display, win);
  578.     XDrawText(display, win, def_gc, x, y, &text, 1);
  579. }
  580.